#include "usrInfo.srpc.h"

#include <workflow/MySQLResult.h>
#include <wfrest/HttpServer.h>
#include <workflow/WFFacilities.h>
#include <map>
#include <iostream>
#include <signal.h>
#include <string>
#include <chrono>
#include "ppconsul/agent.h"
using std::string;
using namespace wfrest;
using namespace srpc;
using namespace protocol;
using namespace ppconsul::agent;

using std::map;
using ppconsul::Consul;

static WFFacilities::WaitGroup wait_group(1);

void sig_handler(int)
{
	wait_group.done();
}

struct UserInfoContext{
     UsrInfoResponse * resp;
	 string username;
};



class UsrInfoServiceImpl : public UsrInfo::Service
{
public:

	void usrInfo(UsrInfoRequest *request, UsrInfoResponse *response, srpc::RPCContext *ctx) override
	{
        

		SeriesWork * series = ctx->get_series();
		string username = request->username();
		string sql = "select * from user_table where username = '"+username+"';";
        WFMySQLTask * mysqltask = WFTaskFactory::create_mysql_task("mysql://root:123@localhost/newCloudDisk",3,&UsrInfoServiceImpl::UserInfomysqlCallback);
    	mysqltask->get_req()->set_query(sql);
		UserInfoContext * context = new UserInfoContext{response,username};
		series->set_context(context);
        series->set_callback([context](const SeriesWork *){
                delete context;
        });
        series->push_back(mysqltask);
		
	}
private:
	static void UserInfomysqlCallback(WFMySQLTask * mysqlTask){
		UserInfoContext * context = static_cast<UserInfoContext*>(series_of(mysqlTask)->get_context());
 	if(mysqlTask->get_state() !=WFT_STATE_SUCCESS){
        context->resp->set_success(0);
        return;
    }

    MySQLResultCursor cursor(mysqlTask->get_resp());

    if(cursor.get_cursor_status()==MYSQL_PACKET_ERROR){
        context->resp->set_success(0);
        return ;
    }

    if(cursor.get_cursor_status()==MYSQL_STATUS_GET_RESULT){
        map<string,MySQLCell> row;
        cursor.fetch_row(row);
        if(row.size()==0){
            context->resp->set_success(0);
            return;
        }
		context->resp->set_success(1);
		context->resp->set_username(context->username);
        context->resp->set_signupat(row["created_at"].as_string());
    }

	}
};

static void timer_callback(WFTimerTask* task)
{
    Agent* agent = (Agent*)task->user_data;
    agent->servicePass("usrInfoService1");

    WFTimerTask* next = WFTaskFactory::create_timer_task(7, 0, timer_callback);
    next->user_data = task->user_data;

    series_of(task)->push_back(next);
}

int main()
{
    signal(SIGINT,sig_handler); 
    GOOGLE_PROTOBUF_VERIFY_VERSION;

    unsigned short port = 1413;
    SRPCServer server;
    UsrInfoServiceImpl usrInfo_impl;
    server.add_service(&usrInfo_impl);

    if(server.start(port) == 0){
        
        Consul consul { "http://127.0.0.1:8500", ppconsul::kw::dc="dc1" };
        Agent agent { consul };
        // 注册服务 
        agent.registerService(
        kw::id = "usrInfoService1",
        kw::name = "usrInfoService",
        kw::address = "127.0.0.1",
        kw::port = 1413,
        kw::check = TtlCheck(std::chrono::seconds{ 10 })
        );

        WFTimerTask* timerTask = WFTaskFactory::create_timer_task("timer",7, 0, timer_callback);
        timerTask->user_data = &agent;
        timerTask->start();

        wait_group.wait();
        server.stop();
        google::protobuf::ShutdownProtobufLibrary();
        
    }else{
        std::cerr << "Error: start signserver failed!\n";
        std::exit(1);
    }

    return 0;
}